#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <iostream>
#include <QDataStream>
#include <QLabel>
#include <QMovie>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    blockSize(0)
{
    ui->setupUi(this);

    // QTcpSocket
    connect( &m_clientSocket, SIGNAL( connected() ), this, SLOT( slot_connect() ) );
    connect( &m_clientSocket, SIGNAL( disconnected() ), this, SLOT( slot_disconnect() ) );
    connect( &m_clientSocket, SIGNAL( error(QAbstractSocket::SocketError) ), this, SLOT( slot_errorSocket(QAbstractSocket::SocketError) ) );
    connect( &m_clientSocket, SIGNAL( readyRead() ), this, SLOT( slot_readData() ) );
}

MainWindow::~MainWindow()
{
    disconnect(&m_clientSocket, SIGNAL( connected() ), this, SLOT( slot_connect() ) );
    disconnect( &m_clientSocket, SIGNAL( disconnected() ), this, SLOT( slot_disconnect() ) );
    disconnect( &m_clientSocket, SIGNAL( error(QAbstractSocket::SocketError) ), this, SLOT( slot_errorSocket(QAbstractSocket::SocketError) ) );
    disconnect( &m_clientSocket, SIGNAL( readyRead() ), this, SLOT( slot_readData() ) );

    delete ui;
}

void MainWindow::slot_connect()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    this->ui->statusBar->showMessage(__PRETTY_FUNCTION__);

    ui->connectButton->setParent(0);

    // ConnectionStatusForm
    connectionStatus = new ConnectionStatusForm(this);
    connectionStatus->display(m_clientSocket.peerAddress().toString(), m_clientSocket.peerPort());

    connect( connectionStatus, SIGNAL( deconnectionAsked() ), this, SLOT( on_deconnection() ) );

    ui->mainGridLayout->addWidget(connectionStatus);

    // CardControllerForm
    controllerForm = new CardControllerForm(this);

    connect( controllerForm, SIGNAL( ledOn() ), this, SLOT( on_ledOn() ) );
    connect( controllerForm, SIGNAL( ledOff() ), this, SLOT( on_ledOff() ) );
    connect( controllerForm, SIGNAL( actualized() ), this, SLOT( on_actualized() ) );
    connect( controllerForm, SIGNAL( messageSent(QString) ), this, SLOT( on_messageSent(QString) ) );
    connect( controllerForm, SIGNAL( motorSlide(int) ), this, SLOT( on_sliderSet(int) ) );

    ui->mainGridLayout->addWidget(controllerForm);

    controllerForm->show();
    connectionStatus->show();
}
void MainWindow::on_deconnection()
{
    m_clientSocket.close();
}

void MainWindow::slot_disconnect()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    this->ui->statusBar->showMessage(__PRETTY_FUNCTION__);

    controllerForm->setParent(0);

    delete controllerForm;
    delete connectionStatus;

    ui->connectButton->setParent(this);
    ui->mainGridLayout->addWidget(ui->connectButton);
    ui->connectButton->show();
}

void MainWindow::slot_errorSocket(QAbstractSocket::SocketError error)
{
    QString message;
    switch(error) // On affiche un message différent selon l'erreur qu'on nous indique
    {
        case QAbstractSocket::HostNotFoundError:
            message = "ERREUR : le serveur n'a pas pu être trouvé. Vérifiez l'IP et le port";
            break;
        case QAbstractSocket::ConnectionRefusedError:
            message = "ERREUR : le serveur a refusé la connexion. Vérifiez si le programme \"serveur\" a bien été lancé. Vérifiez aussi l'IP et le port.";
            break;
        case QAbstractSocket::RemoteHostClosedError:
           message = "ERREUR : le serveur a coupé la connexion.";
            break;
        default:
            message = "ERREUR : " + m_clientSocket.errorString();
    }

    std::cout << __PRETTY_FUNCTION__ << std::endl;
    this->ui->statusBar->showMessage(message);
}

void MainWindow::on_connectButton_clicked()
{
    // ConnectForm
    connectForm = new ConnectForm();
    connectForm->setWindowModality(Qt::ApplicationModal);
    connect( connectForm, SIGNAL(connectionAsked(QHostAddress,qint16)), this, SLOT( slot_connectionAsked(QHostAddress,qint16)) );
    connectForm->show();
}

void MainWindow::slot_connectionAsked(QHostAddress address, qint16 port)
{
    m_clientSocket.connectToHost(address, port);
    connectForm->close();
    delete connectForm;

    if( ! m_clientSocket.waitForConnected(10000) )
    {
        emit m_clientSocket.error(m_clientSocket.error());
    }
}

void MainWindow::slot_readData()
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    QByteArray data = m_clientSocket.readAll();
    std::cout << data.toStdString() << std::endl;
    controllerForm->display(data);
}

void MainWindow::on_ledOn()
{
    ui->statusBar->showMessage("Allumer led");
    if( m_clientSocket.isOpen() )
    {
        sendCommande("ledOn");
        std::cout << "Send : Allumer led" << std::endl;
    }
}

void MainWindow::on_ledOff()
{
    ui->statusBar->showMessage("Eteindre led");
    if( m_clientSocket.isOpen() )
    {
        sendCommande("ledOff");
        std::cout << "Send : Eteindre led" << std::endl;
    }
}

void MainWindow::on_actualized()
{
    QString message = "Actualize";
    std::cout << message.toStdString() << std::endl;
    ui->statusBar->showMessage(message);
    sendCommande("getTemp");
}

void MainWindow::on_messageSent(QString message)
{
    if( m_clientSocket.isOpen() )
    {
        sendMessage(message);
    }
}

void MainWindow::on_sliderSet(int angle){

    ui->statusBar->showMessage("rotation du moteur");
    if( m_clientSocket.isOpen() )
    {
        QString commande = QString("spin %1").arg(angle);
        sendCommande(commande);
        std::cout << "Send : Rotation Moteur" << std::endl;
        std::cout << commande.toStdString() << std::endl;
    }

}

void MainWindow::sendCommande(QString commande)
{
    QString data = "cmd: " + commande;
    m_clientSocket.write(data.toStdString().c_str());
}

void MainWindow::sendMessage(QString message)
{
    QString data = "msg: " + message;
    m_clientSocket.write(data.toStdString().c_str());
}
